//
//  OTA.swift
//  DaRings
//
//  Created by 尹琼 on 2022/11/26.
//

import UIKit
import Moya
import HandyJSON


public final class OTAProvider: NSObject {
    
    
    public func upgrade(target: OTATargetType, type: FileType = .normal, sucess: ((_ fileINfo: FileInfo?) ->Void)?, failure: API.failureHandle?) {
        
        API.OTA(target: target).response { response in
            
            guard let json = try? response.mapJSON(failsOnEmptyData: true) as? [String: Any] else {
                return
            }
            
            let model = FileInfo.deserialize(from: json)
            model?.filePath = type.path
            
            if model?.isEmpty == true {
                print("OTA 是最新版本了")
                sucess?(nil)
                return
            }
            
            sucess?(model)
            
        } failure: { error in
            
            print("OTA 接口出错")
            failure?(error)
            
        }
        
    }
    
    public func download(fileInfo: FileInfo, progress: ProgressBlock?, sucess: ((_ fileINfo: FileInfo?) ->Void)?, failure: API.failureHandle?) {
        
        API.download(target: .download(url: fileInfo.url, filePath: fileInfo.filePath)).response { p in
            
            progress?(p)
            
        } sucess: { response in
            
            if response.statusCode == 200 {
                
                /// 保存 固件信息
                fileInfo.save(of: fileInfo.type)
                
                /// 上传固件给设备
                BluetoothManager.shared.startGoodixUpgradeFromFile(zipPath: fileInfo.filePath)
                
                sucess?(fileInfo)
        
            } 
            
        } failure: { error in
            print("OTA 下载出错")
            failure?(error)
        }
        
        
        
    }
    
}

extension OTAProvider {
    
   public enum FileType: Int, HandyJSONEnum {
        
        case normal = 0
        case beta = 1
        case forced = 2
        
    }
    
    
   public class FileInfo: HandyJSON {
        
        /// 升级类型
        /// NORMAL = 0
        /// BETA = 1
        /// FORCED = 2
       public var type: FileType = .normal
        
        /// 芯片版本
       public var mcu: Int = 0
        
        /// 固件版本
       public var version: String = ""
        
        /// 固件文件的md5 值
       public var md5: String = ""
        
        /// 固件文件路径
       public var filePath: String = ""
        
        /// 固件文件下载链接
       public var url: String = ""
       
       /// log en
       public var log_en: String = ""
       
       /// log
       public var log: String = ""
       
      
       required public init() {}
        
        public static func info(of type: FileType) ->FileInfo? {
            
            let dict = UserDefaults.standard.dictionary(forKey: type.fileName)
            return FileInfo.deserialize(from: dict)
            
        }
        
        public func save(of type: FileType) {
            
            let dict = self.toJSON()
            UserDefaults.standard.set(dict, forKey: type.fileName)
            
        }
       
       public static func remove(of type: FileType) {
           UserDefaults.standard.removeObject(forKey: type.fileName)
       }
       
   }
    
}

extension OTAProvider.FileType {
    
    public var fileName: String {
        
        switch self {
            
        case .normal:
            return "/RTKUpgrade.bin"
        case .beta:
            return "/RTKUpgrade_beta.bin"
        case .forced:
            return "/RTKUpgrade_forced.bin"
            
        }
        
    }
    
   public var path: String {
        
       let rootPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
       let path = rootPath + self.fileName
       return path
    }
    
    public func APITargetType(mac: String, version: String) -> OTATargetType {
        
        switch self {
        case .normal:
            return OTATargetType.production(mac: mac, version: version)
        case .beta:
            return OTATargetType.beta(mac: mac, version: version)
        case .forced:
            return OTATargetType.forced(mac: mac, version: version)
        }
        
    }
    
}

extension OTAProvider.FileInfo: Equatable {
    
    public var isEmpty: Bool {
        
        return md5.isEmpty || filePath.isEmpty || url.isEmpty || version.isEmpty
    }
    
    public static func == (lhs: OTAProvider.FileInfo, rhs: OTAProvider.FileInfo) -> Bool {
        
        return lhs.isEmpty == rhs.isEmpty && lhs.type == rhs.type
    }
}
